/*
 * $Id
 */

#ifdef __linux

#include <xp/bas/lnxapi.h>
#include <xp/bas/errno.h>
#include <xp/bas/stdarg.h>
#include <xp/bas/locale.h>

/*#include <linux/unistd.h>*/
#include <asm/unistd.h>

static inline _syscall0 (xp_uid_t, getuid);
static inline _syscall0 (xp_uid_t, geteuid);
static inline _syscall0 (xp_gid_t, getgid);
static inline _syscall0 (xp_gid_t, getegid);

static inline _syscall0 (xp_pid_t, getpid);
static inline _syscall0 (xp_pid_t, getppid);
static inline _syscall0 (xp_pid_t, setsid);

static inline _syscall1 (xp_pid_t, getpgid, xp_pid_t, pid);
static inline _syscall2 (int, setpgid, xp_pid_t, pid, xp_pid_t, pgid);

static inline _syscall0 (xp_pid_t, fork);
static inline _syscall2 (int, clone, int, flags, void*, child_stack);
static inline _syscall3 (
	xp_pid_t, waitpid, xp_pid_t, pid, int*, status, int, options);

static inline _syscall1 (int, pipe, int*, fd);

static inline _syscall1 (
	xp_mode_t, umask, xp_mode_t, mode);
static inline _syscall3 (
	int, open, const char*, file, int, flag, xp_mode_t, mode);
static inline _syscall1 (
	int, close, int, handle);
static inline _syscall3 (
	int, read, int, handle, void*, buf, xp_size_t, sz);
static inline _syscall3 (
	int, write, int, handle, const void*, data, xp_size_t, sz);
static inline _syscall3 (
	int, lseek, int, handle, xp_off_t, offset, int, whence);
static inline _syscall2 (
	int, fstat, int, handle, xp_stat_t*, buf);

static inline _syscall1 (int, unlink, const char*, path);
static inline _syscall2 (int, mkdir, const char*, path, xp_mode_t, mode);
static inline _syscall2 (int, access, const char*, path, int, option);
static inline _syscall2 (int, chmod, const char*, path, xp_mode_t, mode);

xp_uid_t xp_getuid (void)
{
	return getuid ();
}

xp_uid_t xp_geteuid (void)
{
	return geteuid ();
}

xp_gid_t xp_getgid (void)
{
	return getgid ();
}

xp_gid_t xp_getegid (void)
{
	return getegid ();
}

xp_pid_t xp_getpid (void)
{
	return getpid ();
}

xp_pid_t xp_getppid (void)
{
	return getppid ();
}

xp_pid_t xp_setsid (void)
{
	return setsid ();
}

xp_pid_t xp_getpgid (xp_pid_t pid)
{
	return getpgid (pid);
}

int xp_setpgid (xp_pid_t pid, xp_pid_t pgid)
{
	return setpgid (pid, pgid);
}

int xp_setpgrp (void)
{
	/*return setpgrp ();*/
	return xp_setpgid (0, 0);
}

xp_pid_t xp_getpgrp (void)
{
	return xp_getpgid (0);
}

xp_pid_t xp_fork (void)
{
	return fork ();
}

xp_pid_t xp_wait (xp_pid_t pid, int *status, int options)
{
	return waitpid (pid, status, options);
}

int xp_pipe (int pfd[2])
{
	return pipe (pfd);
}

xp_mode_t xp_umask (xp_mode_t mode)
{
	return umask (mode);
}

int xp_open (const xp_char_t* path, int flag, ...)
{
	xp_va_list arg;
	xp_mode_t mode;
#ifdef XP_CHAR_IS_WCHAR
	xp_mchar_t path_mb[XP_PATH_MAX + 1];
#endif

	xp_va_start (arg, flag);
	mode = (xp_sizeof(xp_mode_t) < xp_sizeof(int))? 
		xp_va_arg (arg, int): xp_va_arg (arg, xp_mode_t);
	xp_va_end (arg);

#ifdef XP_CHAR_IS_MCHAR
	return open (path, flag, mode);
#else
	if (xp_wcstomcs_strict(path, path_mb, xp_countof(path_mb)) == -1) {
		return -1;
	}
	return open (path_mb, flag, mode);
#endif
}

int xp_close (int handle)
{
	return close (handle);
}

xp_ssize_t xp_read (int handle, void* buf, xp_size_t sz)
{
	return read (handle, buf, sz);
}

xp_ssize_t xp_write (int handle, const void* data, xp_size_t sz)
{
	return write (handle, data, sz);
}

xp_off_t xp_hseek (int handle, xp_off_t offset, int whence)
{
	return lseek (handle, offset, whence);
}

int xp_hstat (int handle, xp_stat_t* buf)
{
	return fstat (handle, buf);
}

#endif
